#模板模式

#一、模板模式的优点和应用
#优点：
#1、可变的部分可以充分扩展，不变的步骤可以充分封装；2、提取公共代码，减少冗余代码，便于维护；3、具体过程可以定制，总体流程方便掌控。

#使用场景：
#1、某超类的子类中有公有的方法，并且逻辑基本相同，可以使用模板模式。必要时可以使用钩子方法约束其行为。具体如本节例子；2、比较复杂的算法，可以把核心算法提取出来，周边功能在子类中实现。例如，机器学习中的监督学习算法有很多，如决策树、KNN、SVM等，但机器学习的流程大致相同，都包含输入样本、拟合（fit）、预测等过程，这样就可以把这些过程提取出来，构造模板方法，并通过钩子方法控制流程。

#二、模板模式的缺点
#1、模板模式在抽象类中定义了子类的方法，即子类对父类产生了影响，部分影响了代码的可读性。


class StockQueryDevice():
    stock_code = "0"
    stock_price = 0.0

    def login(self, usr, pwd):
        pass

    def setCode(self, code):
        self.stock_code = code

    def queryPrice(self):
        pass

    def showPrice(self):
        pass


class WebAStockQueryDevice(StockQueryDevice):
    def login(self, usr, pwd):
        if usr == "myStockA" and pwd == "myPwdA":
            print ("Web A:Login OK... user:%s pwd:%s" % (usr, pwd))
            return True
        else:
            print ("Web A:Login ERROR... user:%s pwd:%s" % (usr, pwd))
            return False

    def queryPrice(self):
        print ("Web A Querying...code:%s " % self.stock_code)
        self.stock_price = 20.00

    def showPrice(self):
        print ("Web A Stock P rice...code:%s price:%s" % (self.stock_code, self.stock_price))



class WebBStockQueryDevice(StockQueryDevice):
    def login(self, usr, pwd):
        if usr == "myStockB" and pwd == "myPwdB":
            print ("Web B:Login OK... user:%s pwd:%s" % (usr, pwd))
            return True
        else:
            print ("Web B:Login ERROR... user:%s pwd:%s" % (usr, pwd))
            return False

    def queryPrice(self):
        print ("Web B Querying...code:%s " % self.stock_code)
        self.stock_price = 30.00

    def showPrice(self):
        print ("Web B Stock Price...code:%s price:%s" % (self.stock_code, self.stock_price))


if __name__ == "__main__":
    web_a_query_dev = WebAStockQueryDevice()
    web_a_query_dev.login("myStockA", "myPwdA")
    web_a_query_dev.setCode("12345")
    web_a_query_dev.queryPrice()
    web_a_query_dev.showPrice()
